﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Aribaccio.Device;

namespace BDPAutodetect.Hardware
{
    /// <summary>
    /// 条码结构信息
    /// </summary>
    public struct BarcodeMessage
    {
        /// <summary>
        /// 时间戳, 指定输入间隔为100毫秒以内时为连续输入 ,大于50 毫秒表示手动输入
        /// </summary>
        private int tsMilliseconds = 60;
        /// <summary>
        /// 字符
        /// </summary>
        private char Char;
        /// <summary>
        /// 暂存条码
        /// </summary>
        private string barCode = string.Empty;

        /// <summary>
        /// 条码信息（保存最终的条码）
        /// </summary>
        public string Barcode;
        /// <summary>
        /// 条码是否有效
        /// </summary>
        public bool IsValid;
        /// <summary>
        /// 最后扫描时间
        /// </summary>
        public DateTime LastTime;

        /// <summary>
        /// 构造函数
        /// </summary>
        public BarcodeMessage()
        {
            Barcode = string.Empty;
            LastTime = DateTime.MinValue;
        }

        /// <summary>
        /// 重置
        /// </summary>
        public void Reset()
        {
            this.IsValid = false;
            this.barCode = string.Empty;
        }

        /// <summary>
        /// 解析扫描器信息
        /// </summary>
        /// <param name="scanerMsg">扫描器信息</param>
        public void Parse(ScanerMessage scanerMsg)
        {
            //虚拟码
            int nVirtKey = scanerMsg.Message & 0xff;
            //扫描码
            int nScanCode = scanerMsg.ParamL & 0xff;
            //解析键盘
            if (!this.ParseKeyBoard(nVirtKey, nScanCode))
            {
                this.LastTime = DateTime.Now;
                return;
            }
            //解析条码，并拼接暂存，接收到回车标记接收完成
            this.ParseoBarCode(nVirtKey);
        }

        /// <summary>
        /// 解析键盘
        /// </summary>
        /// <returns></returns>
        private bool ParseKeyBoard(int nVirtKey, int nScanCode)
        {
            try
            {
                uint uKey = 0;
                byte[] kbArray = new byte[256];
                ScanerHookEx.GetKeyboardState(kbArray);
                bool bResult = ScanerHookEx.ToAscii(nVirtKey, nScanCode, kbArray, ref uKey, 0);
                if (bResult)
                {
                    this.Char = Convert.ToChar(uKey);
                }
                return bResult;
            }
            catch (Exception)
            {
                return false;
            }
        }

        /// <summary>
        /// 解析条码，并拼接暂存，接收到回车标记接收完成
        /// </summary>
        private void ParseoBarCode(int nVirtKey)
        {
            TimeSpan ts = DateTime.Now.Subtract(this.LastTime);
            //检测时间，是否为手动输入，并拼接缓存字符串
            if (ts.TotalMilliseconds > tsMilliseconds)
            {
                barCode = this.Char.ToString();
                this.IsValid = false;
            }
            else
            { 
                //检测是否为键盘钩子（13）
                if (nVirtKey == 13 && barCode.Length > 3)
                {
                    this.Barcode = barCode;
                    this.IsValid = true;
                }
                else
                {
                    this.IsValid = false;
                }
                barCode += this.Char.ToString();               
            }           
            this.LastTime = DateTime.Now;
        }
    }
}
